package com.scheduling.schedule.algorithm.impl;

import com.scheduling.machine.entity.Machine;
import com.scheduling.order.entity.Order;
import com.scheduling.product.entity.Operation;
import com.scheduling.schedule.algorithm.ScheduleAlgorithm;
import com.scheduling.schedule.dto.ScheduleResult;
import com.scheduling.schedule.entity.ProductionTask;
import com.scheduling.schedule.entity.ScheduleDetail;
import com.scheduling.schedule.entity.Tuple2;
import com.scheduling.schedule.entity.WorkOrder;
import com.scheduling.schedule.enums.ScheduleAlgorithmType;
import com.scheduling.schedule.service.MachineLoadService;
import com.scheduling.schedule.service.OperationScheduleService;
import com.scheduling.schedule.service.ScheduleDataService;
import com.scheduling.schedule.service.WorkOrderGenerationService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;

import java.math.BigDecimal;
import java.time.Duration;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Random;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.Collectors;

/**
 * 增强遗传算法排产 - 基于CombineAlgorithm的正确时间管理
 * <p>
 * 核心特性：
 * 1. 使用MultiValueMap管理机器空闲时间段
 * 2. 实现正确的工序依赖拓扑排序
 * 3. 遗传算法优化任务-机器分配和执行顺序
 * 4. 多代进化寻找最优排产方案
 * <p>
 * 完整流程：
 * 1. 输入：订单列表
 * 2. 订单 → 工单生成
 * 3. 工单 → 遗传算法任务优化（基于机器空闲时间表）
 * 4. 输出：完整排产结果
 *
 * @author 开发团队
 */
@Slf4j
@Component("ENHANCED_GENETIC_ALGORITHM")
@RequiredArgsConstructor
public class EnhancedGeneticAlgorithm implements ScheduleAlgorithm {

    private final WorkOrderGenerationService workOrderGenerationService;
    private final MachineLoadService machineLoadService;
    private final ScheduleDataService scheduleDataService;
    private final OperationScheduleService operationScheduleService;

    // 工单映射缓存，用于遗传算法执行过程中快速查找工单信息
    private Map<String, WorkOrder> workOrderCache = new HashMap<>();

    // 遗传算法参数
    private static final int POPULATION_SIZE = 15;           // 种群大小
    private static final int MAX_GENERATIONS = 30;          // 最大进化代数
    private static final double MUTATION_RATE = 0.15;       // 变异率
    private static final double CROSSOVER_RATE = 0.8;       // 交叉率
    private static final int ELITE_SIZE = 2;                // 精英个体数量
    private static final int CONVERGENCE_GENERATIONS = 5;    // 收敛代数

    /**
     * 个体类 - 表示一种排产方案
     */
    private static class Individual {
        private List<TaskGene> chromosome;          // 染色体（任务基因序列）
        private double fitness;                     // 适应度值
        private LocalDateTime makespan;             // 完工时间
        private double utilization;                 // 设备利用率
        private List<ProductionTask> tasks;         // 解码后的生产任务

        public Individual(List<TaskGene> chromosome) {
            this.chromosome = new ArrayList<>(chromosome);
            this.fitness = 0.0;
            this.utilization = 0.0;
        }

        public Individual(Individual other) {
            this.chromosome = other.chromosome.stream()
                    .map(TaskGene::new)
                    .collect(Collectors.toList());
            this.fitness = other.fitness;
            this.makespan = other.makespan;
            this.utilization = other.utilization;
            this.tasks = other.tasks != null ? new ArrayList<>(other.tasks) : null;
        }

        // Getters and Setters
        public List<TaskGene> getChromosome() {
            return chromosome;
        }

        public void setChromosome(List<TaskGene> chromosome) {
            this.chromosome = chromosome;
        }

        public double getFitness() {
            return fitness;
        }

        public void setFitness(double fitness) {
            this.fitness = fitness;
        }

        public LocalDateTime getMakespan() {
            return makespan;
        }

        public void setMakespan(LocalDateTime makespan) {
            this.makespan = makespan;
        }

        public double getUtilization() {
            return utilization;
        }

        public void setUtilization(double utilization) {
            this.utilization = utilization;
        }

        public List<ProductionTask> getTasks() {
            return tasks;
        }

        public void setTasks(List<ProductionTask> tasks) {
            this.tasks = tasks;
        }
    }

    /**
     * 任务基因类 - 表示任务-机器分配和执行顺序
     */
    private static class TaskGene {
        private String workOrderId;     // 工单ID
        private String operationId;     // 工序ID
        private String machineId;       // 分配的机器ID
        private int priority;           // 执行优先级

        public TaskGene(String workOrderId, String operationId, String machineId, int priority) {
            this.workOrderId = workOrderId;
            this.operationId = operationId;
            this.machineId = machineId;
            this.priority = priority;
        }

        public TaskGene(TaskGene other) {
            this.workOrderId = other.workOrderId;
            this.operationId = other.operationId;
            this.machineId = other.machineId;
            this.priority = other.priority;
        }

        // Getters and Setters
        public String getWorkOrderId() {
            return workOrderId;
        }

        public String getOperationId() {
            return operationId;
        }

        public String getMachineId() {
            return machineId;
        }

        public void setMachineId(String machineId) {
            this.machineId = machineId;
        }

        public int getPriority() {
            return priority;
        }

        public void setPriority(int priority) {
            this.priority = priority;
        }
    }

    @Override
    public ScheduleResult schedule(List<Order> orders, LocalDateTime scheduleStartTime) {
        log.info("开始执行增强遗传算法排产，订单数量: {}", orders.size());

        long startTime = System.currentTimeMillis();
        ScheduleResult result = new ScheduleResult();

        try {
            if (orders.isEmpty()) {
                throw new IllegalArgumentException("订单列表不能为空");
            }

            // ========== 第一阶段：订单 → 工单生成 ==========
            List<WorkOrder> workOrders = generateWorkOrders(orders, scheduleStartTime);
            log.info("第一阶段完成：生成了 {} 个工单", workOrders.size());

            // ========== 第二阶段：工单 → 遗传算法任务排产 ==========
            List<ProductionTask> productionTasks = generateProductionTasks(workOrders, scheduleStartTime);
            log.info("第二阶段完成：生成了 {} 个生产任务", productionTasks.size());

            // ========== 第三阶段：生成排产详情 ==========
            List<ScheduleDetail> scheduleDetails = generateScheduleDetails(productionTasks);

            // ========== 计算统计信息 ==========
            LocalDateTime scheduleEndTime = calculateScheduleEndTime(productionTasks);
            BigDecimal totalUtilization = scheduleDataService.calculateTotalUtilization(productionTasks,
                    scheduleStartTime, scheduleEndTime);

            // ========== 封装结果 ==========
            result.setSuccess(true);
            result.setScheduleStartTime(scheduleStartTime);
            result.setScheduleEndTime(scheduleEndTime);
            result.setTotalUtilization(totalUtilization);
            result.setGeneratedWorkOrders(workOrders);
            result.setProductionTasks(productionTasks);
            result.setScheduleDetails(scheduleDetails);
            result.setAlgorithmType(getAlgorithmType());
            result.setAlgorithmDescription(getDescription());
            result.setTotalWorkOrders(workOrders.size());
            result.setTotalTasks(productionTasks.size());
            result.setTotalMachines(calculateMachineCount(productionTasks));
            result.setExecutionTimeMs(System.currentTimeMillis() - startTime);

            log.info("增强遗传算法排产执行完成，工单: {}, 任务: {}, 设备利用率: {}%, 执行耗时: {}ms",
                    workOrders.size(), productionTasks.size(), totalUtilization, result.getExecutionTimeMs());

        } catch (Exception e) {
            log.error("增强遗传算法排产执行失败", e);
            result.setSuccess(false);
            result.setErrorMessage("算法执行失败: " + e.getMessage());
        }

        return result;
    }

    @Override
    public String getAlgorithmType() {
        return ScheduleAlgorithmType.ENHANCED_GENETIC_ALGORITHM.getCode();
    }

    @Override
    public String getDescription() {
        return ScheduleAlgorithmType.ENHANCED_GENETIC_ALGORITHM.getDescription();
    }

    @Override
    public List<WorkOrder> generateWorkOrders(List<Order> orders, LocalDateTime scheduleStartTime) {
        log.info("遗传算法工单生成（保持多样性）");

        List<WorkOrder> workOrders = workOrderGenerationService.generateDefaultWorkOrders(orders, scheduleStartTime);

        // 遗传算法预排序：随机化以保持种群多样性
        Collections.shuffle(workOrders, new Random(System.currentTimeMillis()));

        log.info("遗传算法工单生成完成，总数: {} (保持初始多样性)", workOrders.size());
        return workOrders;
    }

    @Override
    public List<ProductionTask> generateProductionTasks(List<WorkOrder> workOrders, LocalDateTime scheduleStartTime) {
        log.info("执行遗传算法任务优化");

        // 获取机器空闲时间表（使用CombineAlgorithm的高级时间管理）
        MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineAvailableTime =
                getMachineAvailableTime(scheduleStartTime);

        // 执行遗传算法
        List<ProductionTask> optimizedTasks = executeGeneticAlgorithm(workOrders, machineAvailableTime,
                scheduleStartTime);

        log.info("遗传算法优化完成，总任务数: {}", optimizedTasks.size());
        return optimizedTasks;
    }

    /**
     * 执行遗传算法核心逻辑
     */
    private List<ProductionTask> executeGeneticAlgorithm(
            List<WorkOrder> workOrders,
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineAvailableTime,
            LocalDateTime scheduleStartTime) {

        log.debug("开始遗传算法进化，种群大小: {}, 最大代数: {}", POPULATION_SIZE, MAX_GENERATIONS);

        // 初始化工单缓存（重要！确保createTaskFromGene能正确获取工单信息）
        workOrderCache.clear();
        for (WorkOrder workOrder : workOrders) {
            workOrderCache.put(workOrder.getWorkOrderId(), workOrder);
        }
        log.debug("工单缓存初始化完成，缓存数量: {}", workOrderCache.size());

        // 1. 构建任务基因池
        List<TaskGene> genePool = buildTaskGenePool(workOrders);
        log.debug("构建基因池完成，基因数量: {}", genePool.size());

        // 2. 初始化种群
        List<Individual> population = initializePopulation(genePool, machineAvailableTime, scheduleStartTime);
        log.debug("初始化种群完成，个体数量: {}", population.size());

        // 3. 进化迭代
        Individual bestIndividual = null;
        double bestFitness = Double.NEGATIVE_INFINITY;
        int noImprovementCount = 0;

        for (int generation = 0; generation < MAX_GENERATIONS; generation++) {
            // 评估适应度
            for (Individual individual : population) {
                evaluateFitness(individual, machineAvailableTime, scheduleStartTime);
            }

            // 选择最佳个体
            Individual currentBest = population.stream()
                    .max(Comparator.comparingDouble(Individual::getFitness))
                    .orElse(null);

            if (currentBest != null && currentBest.getFitness() > bestFitness) {
                bestFitness = currentBest.getFitness();
                bestIndividual = new Individual(currentBest);
                noImprovementCount = 0;
                log.debug("第 {}代发现更优解，适应度: {:.4f}", generation + 1, bestFitness);
            } else {
                noImprovementCount++;
            }

            // 检查收敛条件
            if (noImprovementCount >= CONVERGENCE_GENERATIONS) {
                log.info("算法收敛，提前终止于第{}代", generation + 1);
                break;
            }

            // 生成下一代
            population = evolveNextGeneration(population, machineAvailableTime, scheduleStartTime);
        }

        log.info("遗传算法进化完成，最佳适应度: {:.4f}", bestFitness);
        return bestIndividual != null ? bestIndividual.getTasks() : new ArrayList<>();
    }

    /**
     * 构建任务基因池
     */
    private List<TaskGene> buildTaskGenePool(List<WorkOrder> workOrders) {
        List<TaskGene> genePool = new ArrayList<>();

        for (WorkOrder workOrder : workOrders) {
            try {
                List<Operation> operations = scheduleDataService.getOperationsByProductId(workOrder.getProductId());
                operationScheduleService.sortOperations(operations); // 确保工序依赖正确

                for (int i = 0; i < operations.size(); i++) {
                    Operation operation = operations.get(i);

                    // 获取可用机器
                    List<String> compatibleMachines = getCompatibleMachines(operation);

                    if (!compatibleMachines.isEmpty()) {
                        // 为每个兼容机器创建基因（提供选择多样性）
                        for (String machineId : compatibleMachines) {
                            TaskGene gene = new TaskGene(
                                    workOrder.getWorkOrderId(),
                                    operation.getOperationId(),
                                    machineId,
                                    i // 工序顺序作为初始优先级
                            );
                            genePool.add(gene);
                        }
                    }
                }
            } catch (Exception e) {
                log.error("为工单 {} 构建基因失败", workOrder.getWorkOrderId(), e);
            }
        }

        return genePool;
    }

    /**
     * 获取工序兼容的机器列表
     */
    private List<String> getCompatibleMachines(Operation operation) {
        try {
            String requiredMachineType = operation.getMachineTypeId();
            List<Machine> machines = scheduleDataService.getMachinesByType(requiredMachineType);

            return machines.stream()
                    .filter(m -> !"故障".equals(m.getStatus()))
                    .map(Machine::getMachineId)
                    .collect(Collectors.toList());
        } catch (Exception e) {
            log.error("获取工序 {} 兼容机器失败", operation.getOperationId(), e);
            return new ArrayList<>();
        }
    }

    /**
     * 初始化种群
     */
    private List<Individual> initializePopulation(
            List<TaskGene> genePool,
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineAvailableTime,
            LocalDateTime scheduleStartTime) {

        List<Individual> population = new ArrayList<>();

        // 按工单分组基因
        Map<String, List<TaskGene>> workOrderGenes = genePool.stream()
                .collect(Collectors.groupingBy(TaskGene::getWorkOrderId));

        for (int i = 0; i < POPULATION_SIZE; i++) {
            List<TaskGene> chromosome = createRandomChromosome(workOrderGenes);
            Individual individual = new Individual(chromosome);
            population.add(individual);
        }

        return population;
    }

    /**
     * 创建随机染色体
     */
    private List<TaskGene> createRandomChromosome(Map<String, List<TaskGene>> workOrderGenes) {
        List<TaskGene> chromosome = new ArrayList<>();
        Random random = new Random();

        for (Map.Entry<String, List<TaskGene>> entry : workOrderGenes.entrySet()) {
            List<TaskGene> genes = entry.getValue();

            // 按工序分组
            Map<String, List<TaskGene>> operationGenes = genes.stream()
                    .collect(Collectors.groupingBy(TaskGene::getOperationId));

            // 为每个工序随机选择一个机器
            for (List<TaskGene> opGenes : operationGenes.values()) {
                TaskGene selectedGene = opGenes.get(random.nextInt(opGenes.size()));
                chromosome.add(new TaskGene(selectedGene));
            }
        }

        // 随机化优先级
        for (int i = 0; i < chromosome.size(); i++) {
            chromosome.get(i).setPriority(random.nextInt(chromosome.size()));
        }

        return chromosome;
    }

    /**
     * 进化下一代种群
     */
    private List<Individual> evolveNextGeneration(
            List<Individual> currentPopulation,
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineAvailableTime,
            LocalDateTime scheduleStartTime) {

        List<Individual> nextGeneration = new ArrayList<>();

        // 精英保留
        currentPopulation.sort((a, b) -> Double.compare(b.getFitness(), a.getFitness()));
        for (int i = 0; i < ELITE_SIZE && i < currentPopulation.size(); i++) {
            nextGeneration.add(new Individual(currentPopulation.get(i)));
        }

        Random random = new Random();

        // 生成新个体
        while (nextGeneration.size() < POPULATION_SIZE) {
            // 锦标赛选择父代
            Individual parent1 = tournamentSelection(currentPopulation);
            Individual parent2 = tournamentSelection(currentPopulation);

            // 交叉
            List<Individual> offspring = crossover(parent1, parent2);

            // 变异
            for (Individual child : offspring) {
                if (random.nextDouble() < MUTATION_RATE) {
                    mutate(child);
                }
                if (nextGeneration.size() < POPULATION_SIZE) {
                    nextGeneration.add(child);
                }
            }
        }

        return nextGeneration;
    }

    /**
     * 锦标赛选择
     */
    private Individual tournamentSelection(List<Individual> population) {
        Random random = new Random();
        int tournamentSize = Math.max(2, population.size() / 4);

        Individual best = null;
        for (int i = 0; i < tournamentSize; i++) {
            Individual candidate = population.get(random.nextInt(population.size()));
            if (best == null || candidate.getFitness() > best.getFitness()) {
                best = candidate;
            }
        }

        return best;
    }

    /**
     * 交叉操作
     */
    private List<Individual> crossover(Individual parent1, Individual parent2) {
        List<Individual> offspring = new ArrayList<>();
        Random random = new Random();

        if (random.nextDouble() < CROSSOVER_RATE) {
            // 单点交叉
            int crossoverPoint = random.nextInt(parent1.getChromosome().size());

            List<TaskGene> child1Chromosome = new ArrayList<>();
            List<TaskGene> child2Chromosome = new ArrayList<>();

            for (int i = 0; i < parent1.getChromosome().size(); i++) {
                if (i < crossoverPoint) {
                    child1Chromosome.add(new TaskGene(parent1.getChromosome().get(i)));
                    child2Chromosome.add(new TaskGene(parent2.getChromosome().get(i)));
                } else {
                    child1Chromosome.add(new TaskGene(parent2.getChromosome().get(i)));
                    child2Chromosome.add(new TaskGene(parent1.getChromosome().get(i)));
                }
            }

            offspring.add(new Individual(child1Chromosome));
            offspring.add(new Individual(child2Chromosome));
        } else {
            // 直接复制父代
            offspring.add(new Individual(parent1));
            offspring.add(new Individual(parent2));
        }

        return offspring;
    }

    /**
     * 变异操作
     */
    private void mutate(Individual individual) {
        Random random = new Random();
        List<TaskGene> chromosome = individual.getChromosome();

        if (!chromosome.isEmpty()) {
            // 随机选择变异类型
            if (random.nextBoolean()) {
                // 机器变异：随机改变一个任务的机器分配
                int geneIndex = random.nextInt(chromosome.size());
                TaskGene gene = chromosome.get(geneIndex);

                try {
                    Operation operation = operationScheduleService.getOperationById(gene.getOperationId());
                    if (operation != null) {
                        List<String> compatibleMachines = getCompatibleMachines(operation);
                        if (!compatibleMachines.isEmpty()) {
                            String newMachine = compatibleMachines.get(random.nextInt(compatibleMachines.size()));
                            gene.setMachineId(newMachine);
                        }
                    }
                } catch (Exception e) {
                    log.debug("机器变异失败", e);
                }
            } else {
                // 优先级变异：随机交换两个任务的优先级
                if (chromosome.size() >= 2) {
                    int index1 = random.nextInt(chromosome.size());
                    int index2 = random.nextInt(chromosome.size());

                    int temp = chromosome.get(index1).getPriority();
                    chromosome.get(index1).setPriority(chromosome.get(index2).getPriority());
                    chromosome.get(index2).setPriority(temp);
                }
            }
        }
    }

    /**
     * 评估个体适应度
     */
    private void evaluateFitness(
            Individual individual,
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineAvailableTime,
            LocalDateTime scheduleStartTime) {

        try {
            // 解码染色体为生产任务
            List<ProductionTask> tasks = decodeChromosome(individual.getChromosome(), machineAvailableTime,
                    scheduleStartTime);
            individual.setTasks(tasks);

            if (tasks.isEmpty()) {
                individual.setFitness(0.0);
                return;
            }

            // 计算完工时间
            LocalDateTime makespan = tasks.stream()
                    .map(ProductionTask::getPlanEndTime)
                    .filter(Objects::nonNull)
                    .max(LocalDateTime::compareTo)
                    .orElse(scheduleStartTime);
            individual.setMakespan(makespan);

            // 计算设备利用率
            double utilization = calculateUtilizationRate(tasks, scheduleStartTime, makespan);
            individual.setUtilization(utilization);

            // 综合适应度函数（最小化完工时间，最大化利用率）
            long makespanMinutes = Duration.between(scheduleStartTime, makespan).toMinutes();
            double fitness = (utilization / 100.0) * 1000.0 - makespanMinutes * 0.1;
            individual.setFitness(fitness);

        } catch (Exception e) {
            log.debug("适应度评估失败", e);
            individual.setFitness(0.0);
        }
    }

    /**
     * 解码染色体为生产任务序列（基于CombineAlgorithm的时间管理）
     */
    private List<ProductionTask> decodeChromosome(
            List<TaskGene> chromosome,
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> initialMachineTime,
            LocalDateTime scheduleStartTime) {

        List<ProductionTask> tasks = new ArrayList<>();
        AtomicInteger taskSequence = new AtomicInteger(1);

        // 复制机器时间表以避免修改原始数据
        MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineAvailableTime =
                copyMachineTimeMap(initialMachineTime);

        // 按优先级排序基因
        List<TaskGene> sortedGenes = chromosome.stream()
                .sorted(Comparator.comparingInt(TaskGene::getPriority))
                .collect(Collectors.toList());

        // 工单进度跟踪
        Map<String, LocalDateTime> workOrderProgress = new HashMap<>();

        for (TaskGene gene : sortedGenes) {
            try {
                ProductionTask task = createTaskFromGene(gene, machineAvailableTime, workOrderProgress,
                        scheduleStartTime, taskSequence);
                if (task != null) {
                    tasks.add(task);
                }
            } catch (Exception e) {
                log.debug("解码基因失败: {}", gene.getOperationId(), e);
            }
        }

        return tasks;
    }

    /**
     * 复制机器时间映射
     */
    @SuppressWarnings("unchecked")
    private MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> copyMachineTimeMap(
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> original) {

        MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> copy =
                new org.springframework.util.LinkedMultiValueMap<>();

        for (String machineId : original.keySet()) {
            List<Tuple2<LocalDateTime, LocalDateTime>> timeSlots = original.get(machineId);
            List<Tuple2<LocalDateTime, LocalDateTime>> copiedSlots = timeSlots.stream()
                    .map(slot -> new Tuple2<>(slot.getFirst(), slot.getSecond()))
                    .collect(Collectors.toList());
            copy.put(machineId, copiedSlots);
        }

        return copy;
    }

    /**
     * 从基因创建生产任务
     */
    private ProductionTask createTaskFromGene(
            TaskGene gene,
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machineTime,
            Map<String, LocalDateTime> workOrderProgress,
            LocalDateTime scheduleStartTime,
            AtomicInteger taskCounter) {

        try {
            // 获取工单和工序信息
            WorkOrder workOrder = getWorkOrderById(gene.getWorkOrderId());
            Operation operation = operationScheduleService.getOperationById(gene.getOperationId());

            if (workOrder == null || operation == null) {
                return null;
            }

            // 确定任务开始时间（考虑工序依赖）
            LocalDateTime earliestStart = workOrderProgress.getOrDefault(gene.getWorkOrderId(), scheduleStartTime);

            // 获取机器空闲时间
            String machineId = gene.getMachineId();
            List<Tuple2<LocalDateTime, LocalDateTime>> freeTimes = machineTime.get(machineId);
            if (freeTimes == null || freeTimes.isEmpty()) {
                return null;
            }

            // 计算任务数量（考虑机器产能）
            int workOrderQuantity = workOrder.getQuantity() != null ? workOrder.getQuantity() : 1;
            int standardTime = operation.getStandardTime() != null ? operation.getStandardTime() : 60;

            // 计算实际任务数量和时间（修复重大bug：时间计算错误）
            int taskQuantity = workOrderQuantity; // 使用工单的完整数量

            // ⚠️ 重要修复：标准时间应该乘以数量，与其他算法保持一致
            // 标准做法：总时间 = standardTime * quantity（参考ProductionTaskFactory.java第93行）
            int taskDuration = standardTime * taskQuantity;

            // 寻找合适的时间段
            freeTimes.sort(Comparator.comparing(Tuple2::getFirst));
            for (Tuple2<LocalDateTime, LocalDateTime> freeTime : freeTimes) {
                LocalDateTime slotStart = freeTime.getFirst();
                LocalDateTime slotEnd = freeTime.getSecond();

                // 调整开始时间
                LocalDateTime taskStart = slotStart.isBefore(earliestStart) ? earliestStart : slotStart;
                LocalDateTime taskEnd = taskStart.plusMinutes(taskDuration);

                // 检查是否能安排
                if (slotEnd.equals(LocalDateTime.MAX) || !taskEnd.isAfter(slotEnd)) {
                    // 创建任务
                    ProductionTask task = new ProductionTask();
                    String timeStamp = String.valueOf(System.currentTimeMillis()).substring(7);
                    task.setTaskId("GA_" + timeStamp + String.format("%03d", taskCounter.getAndIncrement()));
                    task.setWorkOrderId(workOrder.getWorkOrderId());
                    task.setOperationId(operation.getOperationId());
                    task.setMachineId(machineId);
                    task.setQuantity(taskQuantity);
                    task.setStatus("已分配");
                    task.setStandardTime(taskDuration);
                    task.setPlannedTime(taskDuration);
                    task.setPlanStartTime(taskStart);
                    task.setPlanEndTime(taskEnd);
                    task.setCreateTime(LocalDateTime.now());
                    task.setUpdateTime(LocalDateTime.now());

                    // 更新机器时间和工单进度
                    updateMachineAvailableTime(machineTime, machineId, new Tuple2<>(taskStart, taskEnd));
                    workOrderProgress.put(gene.getWorkOrderId(), taskEnd);

                    return task;
                }
            }
        } catch (Exception e) {
            log.debug("创建任务失败", e);
        }

        return null;
    }

    /**
     * 从缓存中获取工单信息（修复quantity=1的bug）
     */
    private WorkOrder getWorkOrderById(String workOrderId) {
        WorkOrder workOrder = workOrderCache.get(workOrderId);
        if (workOrder == null) {
            log.warn("工单缓存中未找到工单: {}", workOrderId);
            // 创建默认工单作为兜底，但这种情况不应该发生
            workOrder = new WorkOrder();
            workOrder.setWorkOrderId(workOrderId);
            workOrder.setQuantity(1);
        }
        return workOrder;
    }

    /**
     * 更新机器空闲时间表（复用CombineAlgorithm逻辑）
     */
    private void updateMachineAvailableTime(
            MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> machinesAvailableTime,
            String machineId,
            Tuple2<LocalDateTime, LocalDateTime> usedInterval) {

        LocalDateTime taskStart = usedInterval.getFirst();
        LocalDateTime taskEnd = usedInterval.getSecond();

        List<Tuple2<LocalDateTime, LocalDateTime>> machineFreeTime = machinesAvailableTime.get(machineId);
        Iterator<Tuple2<LocalDateTime, LocalDateTime>> iterator = machineFreeTime.iterator();
        List<Tuple2<LocalDateTime, LocalDateTime>> newSlots = new ArrayList<>();

        while (iterator.hasNext()) {
            Tuple2<LocalDateTime, LocalDateTime> slot = iterator.next();
            LocalDateTime slotStart = slot.getFirst();
            LocalDateTime slotEnd = slot.getSecond();

            if (!taskStart.isBefore(slotStart) && !taskEnd.isAfter(slotEnd)) {
                iterator.remove();

                if (slotStart.isBefore(taskStart)) {
                    newSlots.add(new Tuple2<>(slotStart, taskStart));
                }

                if (taskEnd.isBefore(slotEnd)) {
                    newSlots.add(new Tuple2<>(taskEnd, slotEnd));
                }

                break;
            }
        }

        machineFreeTime.addAll(newSlots);
        machineFreeTime.sort(Comparator.comparing(Tuple2::getFirst));
    }

    /**
     * 获取机器空闲时间表（使用CombineAlgorithm的高级时间管理）
     */
    private MultiValueMap<String, Tuple2<LocalDateTime, LocalDateTime>> getMachineAvailableTime(LocalDateTime scheduleStartTime) {
        return machineLoadService.getCurrentMachineAvailablePeriod(scheduleStartTime);
    }

    /**
     * 计算设备利用率
     */
    private double calculateUtilizationRate(List<ProductionTask> tasks, LocalDateTime startTime,
                                            LocalDateTime endTime) {
        if (tasks.isEmpty()) return 0.0;

        long totalMinutes = Duration.between(startTime, endTime).toMinutes();
        if (totalMinutes <= 0) return 0.0;

        long workMinutes = tasks.stream()
                .mapToLong(task -> task.getPlannedTime() != null ? task.getPlannedTime() : 0)
                .sum();

        int machineCount = (int) tasks.stream()
                .map(ProductionTask::getMachineId)
                .filter(Objects::nonNull)
                .distinct()
                .count();

        if (machineCount <= 0) return 0.0;

        long totalMachineMinutes = totalMinutes * machineCount;
        return (double) workMinutes / totalMachineMinutes * 100.0;
    }

    private List<ScheduleDetail> generateScheduleDetails(List<ProductionTask> productionTasks) {
        List<ScheduleDetail> details = new ArrayList<>();
        AtomicInteger sequence = new AtomicInteger(1);
        String timeStamp = String.valueOf(System.currentTimeMillis()).substring(7);

        for (ProductionTask task : productionTasks) {
            ScheduleDetail detail = new ScheduleDetail();
            detail.setDetailId("GA_DETAIL_" + timeStamp + String.format("%03d", sequence.getAndIncrement()));
            detail.setTaskId(task.getTaskId());
            detail.setMachineId(task.getMachineId());
            detail.setScheduledStartTime(task.getPlanStartTime());
            detail.setScheduledEndTime(task.getPlanEndTime());
            detail.setSequenceNo(sequence.get());
            detail.setCreateTime(LocalDateTime.now());

            details.add(detail);
        }

        return details;
    }

    private LocalDateTime calculateScheduleEndTime(List<ProductionTask> productionTasks) {
        return productionTasks.stream()
                .map(ProductionTask::getPlanEndTime)
                .filter(Objects::nonNull)
                .max(LocalDateTime::compareTo)
                .orElse(LocalDateTime.now());
    }


    private int calculateMachineCount(List<ProductionTask> productionTasks) {
        return (int) productionTasks.stream()
                .map(ProductionTask::getMachineId)
                .filter(Objects::nonNull)
                .distinct()
                .count();
    }
} 